import { forEachValue } from '../util'

/**
 * Vuex中模块的概念
 */
export default class Module {
  constructor (rawModule, runtime) {
    // runtime的作用是什么？
    // runtime为true的情况是通过registerModule方法动态注册模块时为true，此时可以通过
    // unregisterModule方法卸载动态注册的模块，但是不是动态注册模块不可以通过unregisterModule方法
    // 卸载，runtime属性就是为了标记是否为动态注册模块，防止被动态卸载。
    this.runtime = runtime
    // 存放当前模块的子模块Module对象
    this._children = Object.create(null)
    // 当前模块的最原始模块数据
    this._rawModule = rawModule
    const rawState = rawModule.state
    // state属性用于保存当前模块中的状态，状态可以是对象或者函数
    // 状态可为函数是为了防止一个store在多个Vue实例中被注册时，会造成状态state共享，
    // 原因与Vue的data属性一样
    this.state = (typeof rawState === 'function' ? rawState() : rawState) || {}
  }

  get namespaced () {
    return !!this._rawModule.namespaced
  }

  // 保存当前模块的子模块
  addChild (key, module) {
    this._children[key] = module
  }

  // 移除当前模块的子模块
  removeChild (key) {
    delete this._children[key]
  }

  // 获取当前模块的子模块
  getChild (key) {
    return this._children[key]
  }

  update (rawModule) {
    this._rawModule.namespaced = rawModule.namespaced
    if (rawModule.actions) {
      this._rawModule.actions = rawModule.actions
    }
    if (rawModule.mutations) {
      this._rawModule.mutations = rawModule.mutations
    }
    if (rawModule.getters) {
      this._rawModule.getters = rawModule.getters
    }
  }

  forEachChild (fn) {
    forEachValue(this._children, fn)
  }

  forEachGetter (fn) {
    if (this._rawModule.getters) {
      forEachValue(this._rawModule.getters, fn)
    }
  }

  forEachAction (fn) {
    if (this._rawModule.actions) {
      forEachValue(this._rawModule.actions, fn)
    }
  }

  forEachMutation (fn) {
    if (this._rawModule.mutations) {
      forEachValue(this._rawModule.mutations, fn)
    }
  }
}
